from exts import db


# 用户表模型
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True,
                   comment='用户ID')
    name = db.Column(db.String(45), nullable=False,
                     comment='用户名')
    password = db.Column(db.String(65), nullable=False,
                         comment='密码')
    role = db.Column(db.String(45), nullable=False,
                     comment='角色（权限）')
    create_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            comment='创建时间，默认当前时间')
    update_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            onupdate=db.func.current_timestamp(),
                            comment='更新时间，默认当前时间，更新时自动更新')
    # 关联关系
    # 一对多:一个用户可以创建多个数据集，一个数据集只能属于一个用户
    # backref='user' 可以从 Dataset 模型反向引用 User 模型，lazy='dynamic' 表示查询时使用动态加载
    datasets = db.relationship('Dataset', backref='user', lazy='dynamic')
    models = db.relationship('Model', backref='user', lazy='dynamic')
    predicts = db.relationship('Predict', backref='user', lazy='dynamic')


# 植物表模型
class Plant(db.Model):
    __tablename__ = 'plant'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True,
                   comment='植物ID')
    name = db.Column(db.String(200), nullable=False, unique=True,
                     comment='植物的名字')
    description = db.Column(db.String(200), nullable=True,
                            comment='植物的描述')
    picture = db.Column(db.String(200), nullable=True,
                        comment='植物的图片')
    create_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            comment='创建时间，默认当前时间')
    update_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            onupdate=db.func.current_timestamp(),
                            comment='更新时间，默认当前时间，更新时自动更新')
    # 关联关系
    datasets = db.relationship('Dataset', backref='plant', lazy='dynamic')
    models = db.relationship('Model', backref='plant', lazy='dynamic')
    predicts = db.relationship('Predict', backref='plant', lazy='dynamic')


# 数据集表模型
class Dataset(db.Model):
    __tablename__ = 'dataset'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True,
                   comment='数据集ID')
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False,
                        comment='用户ID，数据集是哪个用户创建的')
    user_name = db.Column(db.String(200), nullable=False,
                          comment='用户名字')
    plant_id = db.Column(db.Integer, db.ForeignKey('plant.id'), nullable=False,
                         comment='植物ID，数据集是哪种植物的')
    plant_name = db.Column(db.String(200), nullable=False,
                           comment='植物名字')
    dataset_name = db.Column(db.String(200), nullable=False, unique=True,
                             comment='数据集名字')
    chr_all = db.Column(db.Text, nullable=True,
                        comment='涉及染色体的名字')
    chr_count = db.Column(db.Integer, nullable=True,
                          comment='染色体数量')
    sample_count = db.Column(db.Integer, nullable=True,
                             comment='样本数量')
    description = db.Column(db.Text, nullable=True,
                            comment='数据集的描述')
    files = db.Column(db.Text, nullable=True,
                      comment='未处理的多个数据集文件名字')
    file_size = db.Column(db.String(200), nullable=True,
                          comment='处理后数据集bed文件的大小')
    public = db.Column(db.Boolean, nullable=True, default=False,
                       comment='数据集是否公开，默认为false')
    status = db.Column(db.String(200), nullable=True,
                       comment='数据集状态')
    create_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            comment='创建时间，默认当前时间')
    update_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            onupdate=db.func.current_timestamp(),
                            comment='更新时间，默认当前时间，更新时自动更新')
    # 关联关系
    models = db.relationship('Model', backref='dataset', lazy='dynamic')


# 模型表模型
class Model(db.Model):
    __tablename__ = 'model'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True,
                   comment='模型ID')
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False,
                        comment='用户ID，创建这个模型的用户的ID')
    user_name = db.Column(db.String(200), nullable=False,
                          comment='用户名字')
    plant_id = db.Column(db.Integer, db.ForeignKey('plant.id'), nullable=False,
                         comment='植物ID，表明该模型是用于预测哪种植物的')
    plant_name = db.Column(db.String(200), nullable=False,
                           comment='植物名字')
    dataset_id = db.Column(db.Integer, db.ForeignKey('dataset.id'), nullable=False,
                           comment='数据集ID，表明该模型是使用哪个数据集进行训练的')
    dataset_name = db.Column(db.String(200), nullable=False,
                             comment='数据集名字')
    model_name = db.Column(db.String(200), unique=True, nullable=True,
                           comment='模型的名字')
    description = db.Column(db.Text, nullable=True,
                            comment='模型的描述')
    epochs = db.Column(db.Integer, nullable=True,
                       comment='模型训练的总轮数')
    stopped_epochs = db.Column(db.Integer, nullable=True,
                               comment='模型停止训练的轮数')
    public = db.Column(db.Boolean, nullable=True, default=False,
                       comment='模型是否公开，默认为false')
    status = db.Column(db.String(200), nullable=True,
                       comment='模型的状态')
    accuracy = db.Column(db.Float, nullable=True,
                         comment='模型在测试集上的准确率')
    auc = db.Column(db.Float, nullable=True,
                    comment='模型在测试集上的AUC')
    precision = db.Column(db.Float, nullable=True,
                          comment='模型在测试集上的精确率')
    recall = db.Column(db.Float, nullable=True,
                       comment='模型在测试集上的召回率')
    f1 = db.Column(db.Float, nullable=True,
                   comment='模型在测试集上的F1分数')
    metrics_image = db.Column(db.Text, nullable=True,
                              comment='模型在测试集上的性能指标图像')
    confusion_matrix_image = db.Column(db.Text, nullable=True,
                                       comment='模型在测试集上的混淆矩阵图像')
    file_size = db.Column(db.String(200), nullable=True,
                          comment='模型文件的大小')
    create_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            comment='创建时间，默认当前时间')
    update_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            onupdate=db.func.current_timestamp(),
                            comment='更新时间，默认当前时间，更新时自动更新')
    # 关联关系
    predicts = db.relationship('Predict', backref='model', lazy='dynamic')


# 预测记录表模型
class Predict(db.Model):
    __tablename__ = 'predict'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True,
                   comment='预测记录ID')
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False,
                        comment='用户ID，标识进行该预测操作的用户')
    user_name = db.Column(db.String(200), nullable=False,
                          comment='用户名字')
    plant_id = db.Column(db.Integer, db.ForeignKey('plant.id'), nullable=False,
                         comment='植物ID，表明该预测记录是关于哪种植物的')
    plant_name = db.Column(db.String(200), nullable=False,
                           comment='植物名字')
    model_id = db.Column(db.Integer, db.ForeignKey('model.id'), nullable=False,
                         comment='预测模型ID，代表该预测所使用的模型')
    model_name = db.Column(db.String(200), nullable=False,
                           comment='模型名字')
    description = db.Column(db.Text, nullable=True,
                            comment='预测记录的相关描述')
    files = db.Column(db.Text, nullable=True,
                      comment='未处理的多个数据集文件名字')
    chr_all = db.Column(db.Text, nullable=True,
                        comment='涉及的染色体名字')
    chr_count = db.Column(db.Integer, nullable=True,
                          comment='染色体种类的数量，记录此次预测涉及的染色体种类数')
    status = db.Column(db.String(200), nullable=True,
                       comment='预测记录的状态')
    create_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            comment='创建时间，默认当前时间')
    update_time = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp(),
                            onupdate=db.func.current_timestamp(),
                            comment='更新时间，默认当前时间，更新时自动更新')
